home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Borland Plateform / TURBO PASCAL 1.5 for WIN / TDWDOC.PAK / ASMDEBUG.TDW next >
Encoding:
Text File  |  1992-06-08  |  62.2 KB  |  1,809 lines

  1.                      TURBO DEBUGGER FOR WINDOWS
  2.                      Assembler-level debugging
  3.  
  4. This file contains information about Assembler-level debugging.  The
  5. contents of the file are as follows:
  6.  
  7. 1.  When source debugging isn't enough
  8. 2.  The CPU window
  9. 3.  The Code Pane
  10. 4.  The Register and Flags panes
  11. 5.  The Selector pane
  12. 6.  The Data pane
  13. 7.  The Stack pane
  14. 8.  The assembler
  15. 9.  The Dump window
  16. 10. The Registers window
  17. 11. Assembler-specific bugs
  18. 12. Inline assembler tips
  19. 13. Inline assembler keywords
  20.  
  21. The material in this file is for programmers who are familiar with
  22. programming the 80x86 processor family in assembler. You don't need
  23. to use the information in this chapter to debug your programs, but
  24. there are certain problems that might be easier to find using
  25. techniques discussed in this chapter.
  26.  
  27. We explain when you might want to use assembler-level debugging and
  28. describe the CPU window with its built-in disassembler and
  29. assembler. You then learn how to examine and modify raw hex data
  30. bytes, how to peruse the function calling stack, how to examine and
  31. modify the CPU registers, and finally how to examine and modify the
  32. CPU flags.
  33.  
  34.  
  35.  
  36. ===================================================================
  37. 1. When source debugging isn't enough
  38. ===================================================================
  39.  
  40. When you're debugging a program, most of the time you refer to data
  41. and code at the source level; you refer to symbol names exactly as
  42. you typed them in your source code, and you proceed through your
  43. program by executing pieces of source code.
  44.  
  45. Sometimes, however, you can gain insight into a problem by looking
  46. at the exact instructions that the compiler generated, the contents
  47. of the CPU registers, and the contents of the stack. To do this,
  48. you need to be familiar with both the 80x86 family of processors
  49. and with how the compiler turns your source code into machine
  50. instructions. Because many excellent books are available about the
  51. internal workings of the CPU, we won't go into that in detail here.
  52. You can quickly learn how the compiler turns your source code into
  53. machine instructions by looking at the instructions generated for
  54. each line of source code.
  55.  
  56. C++ lets you write lines of source code that perform many actions
  57. at once, and TDW lets you step one source line at a time, not one
  58. expression at a time. However, you sometimes want to know the
  59. result of executing a small piece of one source line. By stepping
  60. through your program one machine instruction at a time, you can
  61. examine intermediate results, although it does require some effort
  62. to figure out how the compiler translated your source statements
  63. into machine code.
  64.  
  65.  
  66.  
  67. ===================================================================
  68. 2. The CPU window
  69. ===================================================================
  70.  
  71. The CPU window shows you the entire state of the CPU. You can
  72. examine
  73.  
  74. o examine and change the bits and bytes that make up your program's
  75.   code and data
  76.  
  77. o access the contents of any area of memory referenced by a
  78.   selector
  79.  
  80. o use the built-in assembler in the Code pane to patch your program
  81.   temporarily by entering instructions exactly as you would type
  82.   assembler source statements
  83.  
  84. o access the underlying bytes of any data structure, display them
  85.   in a number of formats, and change them
  86.  
  87. Open a CPU window by choosing View|CPU from the menu bar. Depending
  88. on what you're viewing in the current window, the new CPU window
  89. comes up positioned at the appropriate code, data, or stack
  90. location, thus providing a convenient method for taking a "low-
  91. level" look at the code, data, or stack location your cursor is
  92. currently on.
  93.  
  94. The following table shows where your cursor will be positioned when
  95. you choose the CPU command:
  96.  
  97.  
  98. ___________________________________________________________________
  99.  
  100.   Current window        CPU pane             Position
  101. ___________________________________________________________________
  102.  
  103.   Stack window          Stack                Current SS:SP
  104.   Module window         Code                 Current CS:IP
  105.   Variable window       Data/Code            Address of item
  106.   Watches window        Data/Code            Address of item
  107.   Inspector window      Data/Code            Address of item
  108.   Breakpoint            Code                 Breakpoint address
  109.     (if not global)
  110. ____________________________________________________________________
  111.  
  112.  
  113. The CPU window has six panes. To go from one pane to the next,
  114. press Tab or Shift-Tab, or click the pane with your mouse. The line
  115. at the top of the CPU window shows what processor type you have
  116. (8086, 80286, 80386, or 80486).
  117.  
  118. o The top left pane (Code pane) shows the disassembled program code
  119.   intermixed with the source lines.
  120.  
  121. o The second top pane (Register pane) shows the contents of the CPU
  122.   registers.
  123.  
  124. o The top right pane (Flags pane) shows the state of the eight CPU
  125.   flags.
  126.  
  127. o The middle left pane (Selector pane--below the Code pane) shows
  128.   all Windows selectors and indicates the general contents of each.
  129.  
  130. o The bottom left pane (Data pane--below the Selector pane) shows a
  131.   raw hex dump of any area of memory you choose.
  132.  
  133. o The bottom right pane (Stack pane) shows the contents of the
  134.   stack.
  135.  
  136. In the Code pane, an arrow shows the current program location
  137. (CS:IP). In the Stack pane, an arrow shows the current stack
  138. pointer (SS:SP).
  139.  
  140. If the highlighted instruction in the Code pane references a memory
  141. location, the memory address and its current contents are displayed
  142. on the top line of the CPU window. This lets you see both where an
  143. instruction operand points in memory and the value that is about to
  144. be read or written over.
  145.  
  146. As with all windows and panes, pressing Alt-F10 pops up the pane's
  147. local menu. If control-key shortcuts are enabled, pressing the Ctrl
  148. key with the highlighted letter of the desired local menu command
  149. executes the command.
  150.  
  151. In the Code, Data, and Stack panes, you can press Ctrl-LeftArrow
  152. and Ctrl-RightArrow to shift the starting display address of the
  153. pane by 1 byte up or down. Pressing these keys is easier than using
  154. the Goto command if you just want to adjust the display slightly.
  155.  
  156.  
  157.  
  158. ===================================================================
  159. 3. The Code pane
  160. ===================================================================
  161.  
  162. This pane shows the disassembled instructions at an address that
  163. you choose. An arrow shows the current program location (CS:IP).
  164.  
  165. There are two ways of choosing an address:
  166.  
  167. o Use the local menu Goto, Origin, Follow, Caller, or Previous
  168.   command.
  169.  
  170. o Position on a code selector in the Selector pane, then choose
  171.   Examine to display the contents of the selector in the Code pane.
  172.  
  173. The left part of each disassembled line shows the address of the
  174. instruction. The address is displayed either as a hex segment and
  175. offset, or with the segment value replaced with the CS register
  176. name if the segment value is the same as the current CS register.
  177. If the window is wide enough (zoomed or resized), the bytes that
  178. make up the instruction are displayed. The disassembled instruction
  179. appears to the right.
  180.  
  181. If the highlighted instruction in the Code pane references a memory
  182. location, the memory address and its current contents are displayed
  183. on the top line of the CPU window. This feature lets you see both
  184. where an instruction operand points in memory and the value that is
  185. about to be read or written over.
  186.  
  187.  
  188. The disassembler
  189. ================
  190.  
  191. The Code pane automatically disassembles and displays your program
  192. instructions. If an address corresponds to either a global symbol,
  193. static symbol, or a line number, the line before the disassembled
  194. instruction displays the symbol if the Mixed display mode is set to
  195. Yes. Also, if there is a line of source code that corresponds to
  196. the symbol address, it is displayed after the symbol.
  197.  
  198. Global symbols appear simply as the symbol name. Static symbols
  199. appear as the module name, followed by a cross hatch (#) for C or
  200. Assembler or a period (.) for Pascal, followed by the static symbol
  201. name. Line numbers appear as the module name, followed by a cross
  202. hatch (#) for C or Assembler or a period (.) for Pascal, followed
  203. by the decimal line number.
  204.  
  205. When an immediate operand is displayed, you can infer its size from
  206. the number of digits: A byte immediate has 2 digits, and a word
  207. immediate has 4 digits.
  208.  
  209. TDW can detect an 8087, 80287, 80387, or 80486 numeric coprocessor
  210. and disassemble those instructions if a floating-point chip or
  211. emulator is present.
  212.  
  213. The instruction mnemonic RETF indicates that this is a far return
  214. instruction. The normal RET mnemonic indicates a near return.
  215.  
  216. Where possible, the target of JMP and CALL instructions is
  217. displayed symbolically. If CS:IP is a JMP or conditional jump
  218. instruction, an up-arrow or down-arrow that shows jump direction
  219. will be displayed only if the executing instruction will cause the
  220. jump to occur. Also, memory addresses used by MOV, ADD, and other
  221. instructions display symbolic addresses.
  222.  
  223.  
  224. The Code pane local menu
  225. ========================
  226.  
  227. If you don't come up in the Code pane, use Tab or Shift-Tab to get
  228. there. Then press Alt-F10 to bring up the local menu.
  229.  ________________
  230. | Goto...          |
  231. | Origin         |
  232. | Follow         |
  233. | Caller         |
  234. | Previous       |
  235. | Search...        |
  236. | View source    |
  237. | Mixed      Yes |
  238. |________________|
  239. | New cs:ip      |
  240. | Assemble...      |
  241. | I/O            |
  242. |________________|
  243.  
  244. Goto
  245. ----
  246.  
  247. After choosing this command, you're prompted for the new address to
  248. go to. You can enter addresses that are outside of your program, to
  249. examine code in the BIOS ROM, inside DOS, and in Windows programs.
  250. See Chapter 9 in the debugger manual for complete information on
  251. entering addresses.
  252.  
  253. The Previous command restores the Code pane to the position it had
  254. before the Goto command was issued.
  255.  
  256.  
  257. Origin
  258. ------
  259.  
  260. Positions you at the current program location as indicated by the
  261. CS:IP register pair. This command is useful when you want to return
  262. to where you started.
  263.  
  264. The Previous command restores the Code pane to the position it had
  265. before the Origin command was issued.
  266.  
  267.  
  268. Follow
  269. ------
  270.  
  271. Positions you at the destination address of the currently high-
  272. lighted instruction. The Code pane is repositioned to display the
  273. code at the address where the currently highlighted instruction
  274. will transfer control. For conditional jumps, the address is shown
  275. as if the jump occurred.
  276.  
  277. This command can be used with the CALL, JMP, conditional jump (JZ,
  278. JNE, LOOP, JCXZ, and so forth) and INT instructions.
  279.  
  280. The Previous command restores the Code pane to the position it had
  281. before the Follow command was selected.
  282.  
  283.  
  284. Caller
  285. ------
  286.  
  287. Positions you at the instruction that called the current interrupt
  288. or subroutine.
  289.  
  290. This command won't always work. If the interrupt routine or
  291. subroutine has pushed data items onto the stack, sometimes TDW
  292. can't figure out where the routine was called from.
  293.  
  294. The Previous command restores the Code pane to the position it had
  295. before the Caller command was selected.
  296.  
  297.  
  298. Previous
  299. --------
  300.  
  301. Restores the Code pane position to the address before the last
  302. command that explicitly changed the display address. Using the
  303. arrow keys and PgUp and PgDn does not cause the position to be
  304. remembered.
  305.  
  306. When you choose Previous, the Code pane position is remembered, so
  307. that repeated use of the Previous command causes the Code pane to
  308. switch back and forth between two addresses.
  309.  
  310.  
  311. Search
  312. ------
  313.  
  314. Lets you enter an instruction or byte list to search for. Enter an
  315. instruction exactly as you would with the Assemble command.
  316.  
  317. Be careful which instructions you try to search for; you should
  318. only search for instructions that don't change the bytes they
  319. assemble to, depending on their location in memory. For example,
  320. searching for the following instructions is no problem:
  321.  
  322.   PUSH  DX
  323.   POP   [DI+4]
  324.   ADD   AX,100
  325.  
  326. but searching for the following instructions can cause unpre-
  327. dictable results:
  328.  
  329.   JE    123
  330.   CALL  MYFUNC
  331.   LOOP  100
  332.  
  333. You can also enter a byte list instead of an instruction. See
  334. Chapter 9 in the debugger manual for more on entering byte lists.
  335.  
  336.  
  337. View Source
  338. -----------
  339.  
  340. This command opens a Module window to show you the source code that
  341. corresponds to the current disassembled instruction. If there is no
  342. corresponding source code (for example, you're in Windows code, or
  343. there's no debugging information), you just stay in the Code pane.
  344.  
  345.  
  346. Mixed
  347. -----
  348.  
  349. Toggles between the three ways of displaying disassembled instruc-
  350. tions and source code:
  351.  
  352. No     No source code is displayed, only disassembled instructions.
  353.  
  354. Yes    Source code lines appear before the first disassembled
  355.        instruction for that source line. The pane is set to this
  356.        display mode if your current module is a high-level language
  357.        source module.
  358.  
  359. Both   Source code lines replace disassembled lines for those lines
  360.        that have corresponding source code; otherwise, the disassem-
  361.        bled instruction appears. Use this mode when you are debugging
  362.        an assembler module, and you want to see the original source
  363.        code, instead of the corresponding disassembled instruction.
  364.        The pane is set to this display mode if your current module is
  365.        an assembler source module.
  366.  
  367. New CS:IP
  368. ---------
  369.  
  370. Sets the program location counter (CS:IP registers) to the current-
  371. ly highlighted address. When you rerun your program, execution
  372. starts at this address. This is useful when you want to skip over a
  373. piece of code without executing it.
  374.  
  375. Use this command with extreme care. If you adjust the CS:IP to a
  376. location where the stack is in a different state than at the
  377. current CS:IP, your program will almost certainly crash. Do not use
  378. this command to set the CS:IP to an address outside the current
  379. routine.
  380.  
  381.  
  382. Assemble
  383. --------
  384.  
  385. Assembles an instruction, replacing the one at the currently
  386. highlighted location. You are prompted for the instruction to
  387. assemble. See the section "The assembler" later in this file for
  388. more details.
  389.  
  390. You can also invoke this command by simply starting to type the
  391. statement you want to assemble. When you do this, a dialog box
  392. appears exactly as if you had specified Assemble.
  393.  
  394.  
  395. I/O
  396. ---
  397.  
  398. Reads or writes a value in the CPU's I/O space and lets you examine
  399. the contents of I/O registers on cards and write to them.
  400.  
  401. It pops up this menu:
  402.  _____________
  403. | In byte...    |
  404. | Out byte...   |
  405. | Read word...  |
  406. | Write word... |
  407. |_____________|
  408.  
  409.     In Byte
  410.     -------
  411.  
  412.     Reads a byte from an I/O port. You are prompted for the I/O port
  413.     whose value you want to examine. Use the Read Word option to read
  414.     from a word-sized I/O port.
  415.  
  416.     Out Byte
  417.     --------
  418.  
  419.     Writes a byte to an I/O port. You are prompted for the I/O port to
  420.     write to and the value you want to write. Use the Write Word option
  421.     to write to a word-sized I/O port.
  422.  
  423.     Read Word
  424.     ---------
  425.  
  426.     Reads a word from an I/O port. You are prompted for the I/O port
  427.     whose value you want to examine. Use the In Byte option to read
  428.     from a byte-sized I/O port.
  429.  
  430.     Write Word
  431.     ----------
  432.  
  433.     Writes a word to an I/O port. You are prompted for the I/O port to
  434.     write to and the value you want to write. Use the Out Byte option
  435.     to write to a byte-sized I/O port.
  436.  
  437. IN and OUT instructions access the I/O space where peripheral
  438. device controllers (such as serial cards, disk controllers, and
  439. video adapters) reside.
  440.  
  441. Be careful when you use these commands. Some I/O devices consider
  442. reading their ports to be a significant event that causes the
  443. device to perform some action, such as resetting status bits or
  444. loading a new data byte into the port. You may disrupt the normal
  445. operation of the program you are debugging or the device with
  446. indiscriminate use of these commands.
  447.  
  448.  
  449.  
  450. ===================================================================
  451. 4. The Register and Flags panes
  452. ===================================================================
  453.  
  454. The Register pane, which is the top pane to the right of the Code
  455. pane, shows the contents of the CPU registers.
  456.  
  457. The top right pane is the Flags pane, which shows the state of the
  458. eight CPU flags. The following table lists the different flags and
  459. how they are shown in the Flags pane:
  460.  
  461. ________________________________________________
  462.  
  463.    Letter in pane             Flag name___
  464.  
  465.       c                         Carry
  466.       z                         Zero
  467.       s                         Sign
  468.       o                         Overflow
  469.       p                         Parity
  470.       a                         Auxiliary carry
  471.       i                         Interrupt enable
  472.       d                         Direction___
  473. ________________________________________________
  474.  
  475. The Register pane local menu
  476. ============================
  477.  
  478. Press Alt-F10 to pop up the Register pane local menu. Or, if
  479. control-key shortcuts are enabled, use the Ctrl key with the first
  480. letter of the desired command to access the command.
  481.  _______________________
  482. | Increment             |
  483. | Decrement             |
  484. | Zero                  |
  485. | Change...               |
  486. | Registers 32-bit   No |
  487. |_______________________|
  488.  
  489. Increment
  490. ---------
  491.  
  492. Adds 1 to the value in the currently highlighted register. This is
  493. an easy way to make small adjustments in the value of a register to
  494. compensate for "off-by-one" bugs.
  495.  
  496.  
  497. Decrement
  498. ---------
  499.  
  500. Subtracts 1 from the value in the currently highlighted register.
  501.  
  502.  
  503. Zero
  504. ----
  505.  
  506. Sets the value of the currently highlighted register to 0.
  507.  
  508. Change
  509. ------
  510.  
  511. Changes the value of the currently highlighted register. You are
  512. prompted for the new value. You can make full use of the expression
  513. evaluator to enter a new value.
  514.  
  515. You can also invoke this command by simply starting to type the new
  516. value for the register. A dialog box appears exactly as if you had
  517. specified Change.
  518.  
  519.  
  520. Registers 32-bit
  521. ----------------
  522.  
  523. On an Intel 80X86 32-bit processor (80386 or later), toggles
  524. between displaying the CPU registers as 16-bit or 32-bit values.
  525. You usually see 16-bit registers, unless you use this command to
  526. set the display to 32-bit registers. You really need to see 32-bit
  527. registers only if you're debugging a program that uses the 32-bit
  528. addressing an arithmetic capabilities of the 386 chip. If you are
  529. debugging a program that uses only 16-bit addressing and
  530. arithmetic, use the 16-bit register display.
  531.  
  532.  
  533. The Flags pane local menu
  534. =========================
  535.        ________
  536.       | Toggle |
  537.       |________|
  538.  
  539. Press Alt-F10 to pop up the Flags pane local menu or, if control-
  540. key shortcuts are enabled, use the Ctrl key with the first letter
  541. of the desired command to access the command.
  542.  
  543.  
  544. Toggle
  545. ------
  546.  
  547. Sets the value of the flag to 0 if it was 1, and to 1 if it was 0.
  548. The value 0 corresponds to "clear," and 1 indicates "set." You can
  549. also press Enter or Spacebar to toggle the value of the currently
  550. highlighted flag.
  551.  
  552.  
  553.  
  554. ===================================================================
  555. 5. The Selector pane
  556. ===================================================================
  557.  
  558. This pane shows a list of protected-mode selectors and indicates
  559. some information about each one.
  560.  
  561. A selector can be either valid or invalid. If valid, the selector
  562. points to a location in the protected-mode descriptor table
  563. corresponding to a memory address. If invalid, the selector is
  564. unused.
  565.  
  566. For a valid selector, the pane shows the following:
  567.  
  568. o if the contents are data or code
  569.  
  570. o if the selector is loaded (present in memory) or unloaded
  571.   (swapped out to disk)
  572.  
  573. o the length of the referenced memory area in bytes
  574.  
  575. o the access mode of the memory area (blank; Read/Write, Up;
  576.   others????)
  577.  
  578. If the selector references a data segment, there's additional
  579. information on the access rights (Read/Write or Read only) and the
  580. direction the segment expands in memory (Up or Down).
  581.  
  582.  
  583. The Selector pane local menu
  584. ============================
  585.  
  586. At the Selector pane, press Alt-F10 to pop up the local menu or, if
  587. control-key shortcuts are enabled, use the Ctrl key with the
  588. highlighted letter of the desired command to access the command.
  589.  
  590. You can use the local menu of the Selector pane to go to a new
  591. selector (the Selector command) or see the contents of the selector
  592. currently highlighted in the Selector pane (the Examine command).
  593. The contents display in either the Code pane or the Data pane,
  594. depending on their nature.
  595.  ____________
  596. | Selector   |
  597. | Examine...   |
  598. |____________|
  599.  
  600. Selector
  601. --------
  602.  
  603. Prompts you to type a selector to display in the pane. You can use
  604. full expression syntax to enter the selector. If you enter a
  605. numeric value, TDW assumes it is decimal unless you use the syntax
  606. of the current language to indicate that the value is hexadecimal.
  607.  
  608. For example, if the current language were C, you could type the
  609. hexadecimal selector value 7F as 0x7F. For Pascal, you'd type it as
  610. $7F. You could also type the decimal value 127 in order to go to
  611. selector 7F.
  612.  
  613. Another method of entering the selector value is to display the CPU
  614. window and check the segment register values. If a register holds
  615. the selector you're interested in, you can enter the name of the
  616. register preceded by an underscore (_). For example, you could type
  617. the data segment register as _DS.
  618.  
  619.  
  620. Examine
  621. -------
  622.  
  623. Displays the contents of the memory area referenced by the current
  624. selector and switches focus to the pane where the contents are
  625. displayed. If the selector points to a code segment, the contents
  626. are diplayed in the Code pane. If the contents are data, they're
  627. displayed in the Data pane.
  628.  
  629.  
  630.  
  631. ===================================================================
  632. 6. The Data pane
  633. ===================================================================
  634.  
  635. This pane shows a raw display of an area of memory you've selected.
  636. The leftmost part of each line shows the address of the data
  637. displayed in that line. The address is displayed either as a hex
  638. segment and offset, or with the segment value replaced with one of
  639. the register names if the segment value is the same as that
  640. register. The Data pane matches registers in the following order:
  641. DS, ES, SS, CS.
  642.  
  643. Next, the raw display of one or more data items is displayed. The
  644. format of this area depends on the display format selected with the
  645. Display As local menu command. If you choose one of the floating-
  646. point display formats (Comp, Float, Real, Double, Extended), a
  647. single floating-point number is displayed on each line. Byte format
  648. displays 8 bytes per line, Word format displays 4 words per line,
  649. and Long format displays 2 long words per line.
  650.  
  651. When the data is displayed as bytes, the rightmost part of each
  652. line shows the display characters that correspond to the data bytes
  653. displayed. TDW displays all byte values as their display
  654. equivalents, so don't be surprised if you see graphics characters
  655. displayed to the right of the hex dump area--these are just the
  656. display equivalents of the hex byte values.
  657.  
  658. If you use the Data pane to examine the contents of the display
  659. memory, the ROM BIOS data area, or the vectors in low memory, you
  660. will see the values that are there when the program being debugged
  661. runs, not the actual values in memory when TDW is running. These
  662. are not the same values that are in these memory areas at the time
  663. you look at them. TDW detects when you're accessing areas of memory
  664. that it uses as well, and it gets the correct data value from where
  665. it stores the user program's copy of these data areas.
  666.  
  667. There are two ways of choosing an address:
  668.  
  669. o Use the local menu Goto, Follow, or Previous command.
  670.  
  671. o Position on a data selector in the Selector pane, then choose
  672.   Examine to display the contents of the selector in the Data pane.
  673.  
  674.  
  675. The Data pane local menu
  676. ========================
  677.  
  678. Once you are positioned in the Data pane, press Alt-F10 to pop up
  679. the local menu or, if control-key shortcuts are enabled, use the
  680. Ctrl key with the first letter of the desired command to access it.
  681.  ______________
  682. | Goto...        |
  683. | Search...      |
  684. | Next         |
  685. | Change...      |
  686. | Follow       |
  687. | Previous     |
  688. |______________|
  689. | Display as   |
  690. | Block        |
  691. |______________|
  692.  
  693. The Data pane local menu lets you go to a new address, search for a
  694. character string, change bytes at the current cursor location,
  695. follow near or far pointer chains, restore a previous address,
  696. change how data appears in the window, and move, change, read, and
  697. write blocks of memory.
  698.  
  699.  
  700. Goto
  701. ----
  702.  
  703. Positions you at an address in your data. Enter the new address you
  704. want to go to. You can enter addresses inside DOS, in resident
  705. utilities, or outside your program, which lets you examine data in
  706. the BIOS data area. See Chapter 9 in the debugger manual for a
  707. complete discussion of how to enter addresses.
  708.  
  709.  
  710. Search
  711. ------
  712.  
  713. Searches for a character string, starting at the current memory
  714. address as indicated by the cursor position. Enter the byte list to
  715. search for. The search does not wrap around from the end of the
  716. segment to the beginning. See Chapter 9 in the debugger manual for
  717. a complete discussion of byte lists.
  718.  
  719. Next
  720. ----
  721.  
  722. Searches for the next instance of the byte list you previously
  723. specified with the Search command.
  724.  
  725.  
  726. Change
  727. ------
  728.  
  729. Lets you change the bytes at the current cursor location. If you're
  730. over an ASCII display or the format is Byte, you're prompted for a
  731. byte list. Otherwise, you're prompted for an item of the current
  732. display type. See Chapter 9 in the debugger manual for a discussion
  733. of byte lists.
  734.  
  735. You can also invoke this command by simply starting to type the new
  736. value or values. This brings up a dialog box exactly as if you had
  737. chosen the Change command.
  738.  
  739.  
  740. Follow
  741. ------
  742.  
  743. Opens a menu that lets you follow near or far pointer chains.
  744.  ________________________
  745. | Near code              |
  746. | Far code               |
  747. |________________________|
  748. | Offset to data         |
  749. | Segment:offset to data |
  750. | Base segment:0 to data |
  751. |________________________|
  752.  
  753.     Near Code
  754.     ---------
  755.  
  756.     This command interprets the word under the cursor in the Data pane
  757.     as an offset into the current code segment as specified by the CS
  758.     register. The Code pane becomes the current pane and is positioned
  759.     to this address.
  760.  
  761.     Far Code
  762.     --------
  763.  
  764.     This command interprets the doubleword under the cursor in the Data
  765.     pane as a far address (segment and offset). The Code pane becomes
  766.     the current pane and is positioned to this address.
  767.  
  768.     Offset to Data
  769.     --------------
  770.  
  771.     This command lets you follow word (near, offset only) pointer
  772.     chains. The Data pane is set to the offset specified by the word in
  773.     memory at the current cursor location.
  774.  
  775.     Segment:Offset to Data
  776.     ----------------------
  777.  
  778.     This command lets you follow long (far, segment, and offset)
  779.     pointer chains. The Data pane is set to the offset specified by the
  780.     two words in memory at the current cursor location.
  781.  
  782.     Base Segment:0 to Data
  783.     ----------------------
  784.  
  785.     This command interprets the word under the cursor as a segment
  786.     address and positions the Data pane to the start of that segment.
  787.  
  788.  
  789. Previous
  790. --------
  791.  
  792. Restores the Data pane address to the address before the last
  793. command that explicitly changed the display address. Using the
  794. arrow keys and PgUp and PgDn does not cause the position to be
  795. remembered.
  796.  
  797. TDW maintains a stack of the last five addresses, so you can
  798. backtrack through multiple uses of the Follow menu or Goto
  799. commands.
  800.  
  801.  
  802. Display As
  803. ----------
  804.  
  805. Lets you choose how data appears in the Data pane. You can choose
  806. from any data format used by C++ and assembler. The menu options
  807. are
  808.      __________
  809.     | Byte     |
  810.     | Word     |
  811.     | Long     |
  812.     | Comp     |
  813.     | Float    |
  814.     | Real     |
  815.     | Double   |
  816.     | Extended |
  817.     |__________|
  818.  
  819.     Byte
  820.     ----
  821.  
  822.     Sets the Data pane to display as hexadecimal bytes. This
  823.     corresponds to the C++ Byte type.
  824.  
  825.     Word
  826.     ----
  827.  
  828.     Sets the Data pane to display as word hexadecimal numbers. The 2-
  829.     byte hexadecimal value is shown. This corresponds to the C int data
  830.     type and the C++ Word type.
  831.  
  832.     Long
  833.     ----
  834.  
  835.     Sets the Data pane to display as long hexadecimal integers. The 4-
  836.     byte hex value is shown. This corresponds to the C++ longint type.
  837.  
  838.     Comp
  839.     ----
  840.  
  841.     Sets the Data pane to display 8-byte integers. The decimal value of
  842.     the integer is shown. This is the C++ Comp (IEEE) data type.
  843.  
  844.     Float
  845.     -----
  846.  
  847.     Sets the Data pane to display as short floating-point numbers. The
  848.     scientific notation floating-point value is shown. This is the same
  849.     as the C++ Single (IEEE) type.
  850.  
  851.     Real
  852.     ----
  853.  
  854.     Sets the Data pane to display C++'s 6-byte floating-point numbers.
  855.     The scientific notation floating-point value is shown. This is the
  856.     C++ Real type.
  857.  
  858.     Double
  859.     ------
  860.  
  861.     Sets the data pane to display 8-byte floating-point numbers. The
  862.     scientific notation floating-point value is shown. This is the same
  863.     as the C++ Double type.
  864.  
  865.     Extended
  866.     --------
  867.  
  868.     Sets the Data pane to display 10-byte floating-point numbers. The
  869.     scientific notation floating-point value is shown. This is the
  870.     internal format used by the 80x87 coprocessor. It also corresponds
  871.     to the C++ Extended (IEEE) type, and the assembler TBYTE type.
  872.  
  873.  
  874. Block
  875. -----
  876.  
  877. Lets you manipulate blocks of memory. You can move, clear and set
  878. memory blocks, and read and write memory blocks to and from disk
  879. files. Block brings up the following menu:
  880.      _________
  881.     | Clear...|
  882.     | Move...   |
  883.     | Set...    |
  884.     | Read...   |
  885.     | Write...  |
  886.     |_________|
  887.  
  888.     Clear
  889.     -----
  890.  
  891.     Sets a contiguous block of memory to zero (0). You are prompted for
  892.     the address and the number of bytes to clear.
  893.  
  894.     Move
  895.     ----
  896.  
  897.     Copies a block of memory from one address to another. You are
  898.     prompted for the source address, the destination address, and how
  899.     many bytes to copy.
  900.  
  901.     Set
  902.     ---
  903.  
  904.     Sets a contiguous block of memory to a specific byte value. You are
  905.     prompted for the address of the block, how many bytes to set, and
  906.     the value to set them to.
  907.  
  908.     Read
  909.     ----
  910.  
  911.     Reads all or a portion of a file into a block of memory. You are
  912.     prompted first for the file name to read from, then for the address
  913.     to read it into, and finally for how many bytes to read.
  914.  
  915.     Write
  916.     -----
  917.  
  918.     Writes a block of memory to a file. You are prompted first for the
  919.     file name to write to, then for the address of the block to write
  920.     and how many bytes to write.
  921.  
  922.  
  923. ===================================================================
  924. 7. The Stack pane
  925. ===================================================================
  926.  
  927. The Stack pane, in the lower right corner of the CPU window, shows
  928. the contents of the stack. An arrow shows the current stack pointer
  929. (SS:IP).
  930.  
  931.  
  932. The Stack pane local menu
  933. =========================
  934.  
  935. At the Stack pane, press Alt-F10 to pop up the local menu or, if
  936. control-key shortcuts are enabled, use the Ctrl key with the first
  937. letter of the desired command to access the command.
  938.  ___________
  939. | Goto...     |
  940. | Origin    |
  941. | Follow    |
  942. | Previous  |
  943. | Change...   |
  944. |___________|
  945.  
  946. Goto
  947. ----
  948.  
  949. Positions you at an address in the stack. Enter the new stack
  950. address. If you want, you can enter addresses outside your pro-
  951. gram's stack, although you would usually use the Data pane to
  952. examine arbitrary data outside your program. See Chapter 9 in the
  953. debugger manual for information about how to enter addresses.
  954.  
  955. The Previous command restores the Stack pane to the position it had
  956. before the Goto command was issued.
  957.  
  958.  
  959. Origin
  960. ------
  961.  
  962. Positions you at the current stack location as indicated by the
  963. SS:SP register pair. This command is useful when you want to return
  964. to where you started.
  965.  
  966. The Previous command restores the Stack pane to the position it had
  967. before the Origin command was issued.
  968.  
  969.  
  970. Follow
  971. ------
  972.  
  973. Positions you at the word in the stack pointed to by the currently
  974. highlighted word. This is useful for following stack-frame threads
  975. back to a calling procedure.
  976.  
  977. The Previous command restores the Stack pane to the position it had
  978. before the Follow command was issued.
  979.  
  980.  
  981. Previous
  982. --------
  983.  
  984. Restores the Stack pane position to the address before the last
  985. command that explicitly changed the display address. Using the
  986. arrow keys and PgUp and PgDn does not cause the position to be
  987. remembered.
  988.  
  989. Repeated use of the Previous command causes the Stack pane to
  990. switch back and forth between two addresses.
  991.  
  992.  
  993. Change
  994. ------
  995.  
  996. Lets you enter a new word value for the currently highlighted stack
  997. word.
  998.  
  999. You can also invoke this command by simply starting to type the new
  1000. value for the highlighted stack item. A dialog box appears, exactly
  1001. as if you had specified the Change command.
  1002.  
  1003.  
  1004.  
  1005. ===================================================================
  1006. 8. The assembler
  1007. ===================================================================
  1008.  
  1009. If you use the Assemble command in the Code pane local menu, TDW
  1010. lets you assemble instructions for the 8086, 80186, 80286, 80386,
  1011. and 80486 processors, and also for the 8087, 80287, and 80387
  1012. numeric coprocessors.
  1013.  
  1014. When you use TDW's built-in assembler to modify your program, the
  1015. changes you make are not permanent. If you reload your program Run|
  1016. Program Reset, or if you load another program using File|Open,
  1017. you'll lose any changes you've made.
  1018.  
  1019. Normally you use the assembler to test an idea for fixing your pro-
  1020. gram. Once you've verified that the change works, you must change
  1021. your source code and recompile and link your program.
  1022.  
  1023. The following sections describe the differences between the built-
  1024. in assembler and the syntax accepted by Turbo C++'s inline
  1025. assembler.
  1026.  
  1027.  
  1028. Operand address size overrides
  1029. ==============================
  1030.  
  1031. For the call (CALL), jump (JMP), and conditional jump (JNE, JL, and
  1032. so forth) instructions, the assembler automatically generates the
  1033. smallest instruction that can reach the destination address. You
  1034. can use the NEAR and FAR overrides before the destination address
  1035. to assemble the instruction with a specific size. For example,
  1036.  
  1037.   CALL FAR XYZ
  1038.   JMP  NEAR A1
  1039.  
  1040.  
  1041. Memory and immediate operands
  1042. -----------------------------
  1043.  
  1044. When you use a symbol from your program as an instruction operand,
  1045. you must tell the built-in assembler whether you mean the contents
  1046. of the symbol or the address of the symbol. If you use just the
  1047. symbol name, the assembler treats it as an address, exactly as if
  1048. you had used the assembler OFFSET operator before it. If you put
  1049. the symbol inside brackets ([ ]), it becomes a memory reference.
  1050. For example, if your program contains the data definition
  1051.  
  1052.   A    DW 4
  1053.  
  1054. then [A] references the area of memory where A is stored.
  1055.  
  1056. When you assemble an instruction or evaluate an assembler
  1057. expression to refer to the contents of a variable, use the name of
  1058. the variable alone or between brackets:
  1059.  
  1060.   mov dx,a
  1061.   mov ax,[a]
  1062.  
  1063. To refer to the address of the variable, use the OFFSET operator:
  1064.  
  1065.   mov ax,offset a
  1066.  
  1067.  
  1068. Operand data size overrides
  1069. ===========================
  1070.  
  1071. For some instructions, you must specify the operand size using one
  1072. of the following expressions before the operand:
  1073.  
  1074.   BYTE PTR
  1075.   WORD PTR
  1076.  
  1077. Here are examples of instructions using these overrides:
  1078.  
  1079.   add BYTE PTR[si],10
  1080.   mov WORD PTR[bp+10],99
  1081.  
  1082. In addition to these size overrides, you can use the following
  1083. overrides to assemble 8087/80287/80387/80486 numeric processor
  1084. instructions:
  1085.  
  1086.   DWORD PTR
  1087.   QWORD PTR
  1088.   TBYTE PTR
  1089.  
  1090. Here are some examples using these overrides:
  1091.  
  1092.   fild QWORD PTR[bx]
  1093.   stp  TBYTE PTR[bp+4]
  1094.  
  1095.  
  1096. String instructions
  1097. ===================
  1098.  
  1099. When you assemble a string instruction, you must include the size
  1100. (byte or word) as part of the instruction mnemonic. The assembler
  1101. does not accept the form of the string instructions that uses a
  1102. sizeless mnemonic with an operand that specifies the size. For
  1103. example, use STOSW rather than STOS WORD PTR[di].
  1104.  
  1105.  
  1106.  
  1107. ===================================================================
  1108. 9. The Dump window
  1109. ===================================================================
  1110.  
  1111. The Dump window shows you a raw data dump of any area of memory. It
  1112. works much like the Data pane in the CPU window, except that, when
  1113. zoomed to full size, the Dump Window show twice as much data on a
  1114. single line.
  1115.  
  1116. See "The Data pane local menu" section earlier in this file for a
  1117. description of the contents and local menu for this window.
  1118.  
  1119. Typically, you'd use this window when you're debugging an assembler
  1120. program at the source level, and you want to take a low-level look
  1121. at some data areas. Use View|Dump to open a Dump window or View|
  1122. Another|Dump to open multiple views on memory areas.
  1123.  
  1124. You can also use this window if you're in an Inspector window, and
  1125. you want to look at the raw bytes that make up the object you are
  1126. inspecting. Use View|Dump to get a Dump window that's positioned to
  1127. the data in the Inspector window.
  1128.  
  1129.  
  1130. ===================================================================
  1131. 10. The Registers window
  1132. ===================================================================
  1133.  
  1134. The Registers window shows you the contents of the CPU registers
  1135. and flags. It works like a combination of the Registers and Flags
  1136. panes in the CPU window. You can shrink the size of your Module
  1137. window and put up a Registers window alongside it.
  1138.  
  1139.  
  1140. See "The Register pane local menu" and "The Flags pane local menu"
  1141. sections earlier in this file for a description of the contents and
  1142. local menus for this window.
  1143.  
  1144. Use this window when you're debugging an assembler program at the
  1145. source level and want to look at the register values.
  1146.  
  1147.  
  1148.  
  1149. =========================================
  1150. 11. Assembler-specific bugs
  1151. =========================================
  1152.  
  1153. This section, which covers some of the common pitfalls of assembly
  1154. language programming, is intended for people who have Turbo Assembler
  1155. or use inline assembler in C++ programs. You should refer to the
  1156. Turbo Assembler User's Guide for a fuller explanation on these
  1157. oft-encountered errors--and tips on how to avoid them.
  1158.  
  1159. Forgetting to return to DOS
  1160. ===========================
  1161.  
  1162. In C++, a program ends automatically when there is no more code to
  1163. execute, even if no explicit termination command was written into the
  1164. program. Not so in assembly language, where only those actions that
  1165. you explicitly request are performed. When you run a program that has
  1166. no command to return to DOS, execution simply continues right past the
  1167. end of the program's code and into whatever code happens to be in the
  1168. adjacent memory.
  1169.  
  1170.  
  1171. Forgetting a RET instruction
  1172. ============================
  1173.  
  1174. The proper invocation of a subroutine consists of a call to the subroutine
  1175. from another section of code, execution of the subroutine, and a return
  1176. from the subroutine to the calling code. Remember to insert a RET
  1177. instruction in each subroutine, so that the RETurn to the calling code
  1178. occurs. When you're typing a program, it's easy to skip a RET and end
  1179. up with an error.
  1180.  
  1181.  
  1182. Generating the wrong type of return
  1183. ===================================
  1184. The PROC directive has two effects. First, it defines a name by which a
  1185. procedure can be called. Second, it controls whether the procedure is a near
  1186. or far procedure.
  1187.  
  1188. The RET instructions in a procedure should match the type of the procedure,
  1189. shouldn't they?
  1190.  
  1191. Yes and no. The problem is that it's possible and often desirable to group
  1192. several subroutines in the same procedure. Since these subroutines lack an
  1193. associated PROC directive, their RET instructions take on the type of the
  1194. overall procedure, which is not necessarily the correct type for the
  1195. individual subroutines.
  1196.  
  1197.  
  1198. Reversing operands
  1199. ==================
  1200.  
  1201. To many people, the order of instruction operands in 8086 assembly language
  1202. seems backward (and there is certainly some justification for this
  1203. viewpoint). If the line
  1204.  
  1205.   mov  ax,bx
  1206.  
  1207. meant "move AX to BX," the line would scan smoothly from left to right, and
  1208. this is exactly the way in which many microprocessor manufacturers have
  1209. designed their assembly languages.
  1210.  
  1211. However, Intel took a different approach with 8086 assembly language; for
  1212. us, the line means "move BX to AX," and that can sometimes cause confusion.
  1213.  
  1214.  
  1215. Forgetting the stack or reserving a too-small stack
  1216. ===================================================
  1217.  
  1218. In most cases, you're treading on thin ice if you don't explicitly allocate
  1219. space for a stack. Programs without an allocated stack sometimes run, but
  1220. there is no assurance that these programs will run under all circumstances.
  1221. DOS programs can have a .STACK directive to reserve space for the stack.
  1222. In Turbo C++ for Windows, you can set the stack size by choosing
  1223. Options|Compiler. For each program, you should reserve more than enough
  1224. space for the deepest stack the program can use.
  1225.  
  1226.  
  1227. Calling a subroutine that wipes out registers
  1228. =============================================
  1229.  
  1230. When you're writing assembler code, it's easy to think of the registers
  1231. as local variables, dedicated to the use of the procedure you're working
  1232. on at the moment. In particular, there's a tendency to assume that
  1233. registers are unchanged by calls to other procedures. It just isn't
  1234. so--the registers are global variables, and each procedure can preserve or
  1235. destroy any or all registers.
  1236.  
  1237.  
  1238. Using the wrong sense for a conditional jump
  1239. ============================================
  1240. The profusion of conditional jumps in assembly language (JE, JNE, JC,
  1241. JNC, JA, JB, JG, and so on) allows tremendous flexibility in writing
  1242. code--and also makes it easy to select the wrong jump for a given purpose.
  1243. Moreover, since condition-handling in assembly language requires at least
  1244. two separate lines, one for the comparison and one for the conditional
  1245. jump (it requires many more lines for complex conditions), assembly
  1246. language condition-handling is less intuitive and more prone to errors than
  1247. condition-handling in C++.
  1248.  
  1249.  
  1250. Forgetting about REP string overrun
  1251. ===================================
  1252.  
  1253. String instructions have a curious property: After they're executed, the
  1254. pointers they use wind up pointing to an address 1 byte away (or 2 bytes
  1255. for a word instruction) from the last address processed. This can cause
  1256. some confusion with repeated string instructions, especially REP SCAS and
  1257. REP CMPS.
  1258.  
  1259.  
  1260. Relying on a zero CX to cover a whole segment
  1261. =============================================
  1262.  
  1263. Any repeated string instruction executed with CX equal to zero does nothing.
  1264. Period. This can be convenient in that there's no need to check for the zero
  1265. case before executing a repeated string instruction; on the other hand,
  1266. there's no way to access every byte in a segment with a byte-sized string
  1267. instruction.
  1268.  
  1269.  
  1270. Using incorrect direction flag settings
  1271. =======================================
  1272.  
  1273. When a string instruction is executed, its associated pointer or pointers--
  1274. SI or DI or both--increment or decrement. It all depends on the state of the
  1275. direction flag.
  1276.  
  1277. The direction flag can be cleared with CLD to cause string instructions to
  1278. increment (count up) and can be set with STD to cause string instructions to
  1279. decrement (count down). Once cleared or set, the direction flag stays in the
  1280. same state until either another CLD or STD is executed, or until the flags
  1281. are popped from the stack with POPF or IRET. While it's handy to be able to
  1282. program the direction flag once and then execute a series of string
  1283. instructions that all operate in the same direction, the direction flag can
  1284. also be responsible for intermittent and hard-to-find bugs by causing the
  1285. behavior of string instructions to depend on code that executed much earlier.
  1286.  
  1287.  
  1288. Using the wrong sense for a repeated string comparison
  1289. ======================================================
  1290.  
  1291. The CMPS instruction compares two areas of memory; the SCAS instruction
  1292. compares the accumulator to an area of memory.  Prefixed by REPE, either
  1293. of these instructions can perform a comparison until either CX becomes
  1294. zero or a not-equal comparison occurs. Unfortunately, it's easy to become
  1295. confused about which of the REP prefixes does what.
  1296.  
  1297.  
  1298. Forgetting about string segment defaults
  1299. ========================================
  1300.  
  1301. Each of the string instructions defaults to using a source segment (if any)
  1302. of DS, and a destination segment (if any) of ES. It's easy to forget this
  1303. and try to perform, say, a STOSB to the data segment, since that's where
  1304. all the data you're processing with non-string instructions normally resides.
  1305.  
  1306.  
  1307. Converting incorrectly from byte to word operations
  1308. ===================================================
  1309. In general, it's desirable to use the largest possible data size (usually
  1310. word, but dword on an 80386) for a string instruction, since string
  1311. instructions with larger data sizes often run faster.
  1312.  
  1313. There are a couple of potential pitfalls here. First, the conversion from a
  1314. byte count to a word count by a simple
  1315.  
  1316.   shr cx,1
  1317.  
  1318. loses a byte if CX is odd, since the least-significant bit is shifted out.
  1319.  
  1320. Second, make sure you remember SHR divides the byte count by two. Using,
  1321. say, STOSW with a byte rather than a word count can wipe out other data
  1322. and cause problems of all sorts.
  1323.  
  1324.  
  1325. Using multiple prefixes
  1326. =======================
  1327.  
  1328. String instructions with multiple prefixes are error-prone and should
  1329. generally be avoided.
  1330.  
  1331.  
  1332. Relying on the operand(s) to a string instruction
  1333. =================================================
  1334.  
  1335. The optional operand or operands to a string instruction are used for data
  1336. sizing and segment overrides only, and do not guarantee that the memory
  1337. location referenced is accessed.
  1338.  
  1339.  
  1340. Wiping out a register with multiplication
  1341. =========================================
  1342.  
  1343. Multiplication--whether 8 bit by 8 bit, 16 bit by 16 bit, or 32 bit by 32
  1344. bit--always destroys the contents of at least one register other than the
  1345. portion of the accumulator used as a source operand.
  1346.  
  1347.  
  1348. Forgetting that string instructions alter several registers
  1349. ===========================================================
  1350.  
  1351. The string instructions, MOVS, STOS, LODS, CMPS, and SCAS, can affect several
  1352. of the flags and as many as three registers during execution of a single
  1353. instruction. When you use string instructions, remember that SI, DI, or
  1354. both either increment or decrement (depending on the state of the direction
  1355. flag) on each execution of a string instruction. CX is also decremented at
  1356. least once, and possibly as far as zero, each time a string instruction with
  1357. a REP prefix is used.
  1358.  
  1359.  
  1360. Expecting certain instructions to alter the carry flag
  1361. ======================================================
  1362.  
  1363. While some instructions affect registers or flags unexpectedly, other
  1364. instructions don't even affect all the flags you might expect them to.
  1365.  
  1366.  
  1367. Waiting too long to use flags
  1368. =============================
  1369.  
  1370. Flags last only until the next instruction that alters them, which is
  1371. usually not very long. It's a good practice to act on flags as soon as
  1372. possible after they're set, thereby avoiding all sorts of potential bugs.
  1373.  
  1374.  
  1375. Confusing memory and immediate operands
  1376. =======================================
  1377.  
  1378. An assembler program may refer either to the offset of a memory variable or
  1379. to the value stored in that memory variable. Unfortunately, assembly language
  1380. is neither strict nor intuitive about the ways in which these two types of
  1381. references can be made, and as a result, offset and value references to a
  1382. memory variable are often confused.
  1383.  
  1384.  
  1385. Failing to preserve everything in an interrupt handler
  1386. ======================================================
  1387.  
  1388. Every interrupt handler should explicitly preserve the contents of all
  1389. registers. While it is valid to preserve explicitly only those registers
  1390. that the handler modifies, it's good insurance just to push all registers
  1391. on entry to an interrupt handler and pop all registers on exit.
  1392.  
  1393.  
  1394. Forgetting group overrides in operands and data tables
  1395. ======================================================
  1396.  
  1397. Segment groups let you partition data logically into a number of areas
  1398. without having to load a segment register every time you want to switch
  1399. from one of those logical data areas to another.
  1400.  
  1401.  
  1402.  
  1403. =========================================
  1404. 12. Inline assembler tips
  1405. =========================================
  1406.  
  1407.  
  1408. Looking at raw hex data
  1409. =======================
  1410.  
  1411. You can use the Data|Add Watch and Data| Evaluate/Modify commands with
  1412. a format modifier to look at raw data dumps. For example, if your
  1413. language is Assembler,
  1414.  
  1415.   [ES:DI],20m
  1416.  
  1417. specifies that you want to look at a raw hex memory dump of the 20 bytes
  1418. pointed to by the ES:DI register pair.
  1419.  
  1420.  
  1421. Source-level debugging
  1422. ======================
  1423.  
  1424. You can step through your assembler code using a Module window just as
  1425. with any of the high-level languages. If you want to see the register
  1426. values, you can put a Registers window to the right of the Module window.
  1427.  
  1428. Sometimes, you may want to use a CPU window and see your source code as
  1429. well.  To do this, open a CPU window and choose the Code pane's Mixed
  1430. command until it reads Both. That way you can see both your source code
  1431. and machine code bytes. Remember to zoom the CPU window (by pressing F5)
  1432. if you want to see the machine code bytes.
  1433.  
  1434.  
  1435. Examining and changing registers
  1436. ================================
  1437.  
  1438. The obvious way to change registers is to highlight a register in either
  1439. a CPU window or Registers window. A quick way to change a register is to
  1440. choose Data|Evaluate/Modify. You can enter an assignment expression that
  1441. directly modifies a register's contents. For example,
  1442.  
  1443.    SI = 99
  1444.  
  1445. loads the SI register with 99.
  1446.  
  1447. Likewise, you can examine registers using the same technique. For example,
  1448.  
  1449.    Alt-D E AX
  1450.  
  1451. shows you the value of the AX register.
  1452.  
  1453.  
  1454.  
  1455. =========================================
  1456. 13. Inline assembler keywords
  1457. =========================================
  1458.  
  1459. This section lists the instruction mnemonics and other special symbols that
  1460. you use when entering instructions with the inline assembler. The keywords
  1461. presented here are the same as those used by Turbo Assembler.
  1462.  
  1463.  
  1464. 8086/80186/80286 instructional mnemonics
  1465. _________________________________________
  1466.   AAA        INC        LIDT**     REPNZ
  1467.   AAD        INSB*      LLDT**     REPZ
  1468.   AAM        INSW*      LMSW**     RET
  1469.   AAS        INT        LOCK       REFT
  1470.   ADC        INTO       LODSB      ROL
  1471.   ADD        IRET       LODSW      ROR
  1472.   AND        JB         LOOP       SAHF
  1473.   ARPL**     JBE        LOOPNZ     SAR
  1474.   BOUND*     JCXZ       LOOPZ      SBB
  1475.   CALL       JE         LSL**      SCASB
  1476.   CLC        JL         LTR**      SCASW
  1477.   CLD        JLE        MOV        SGDT**
  1478.   CLI        JMP        MOVSB      SHL
  1479.   CLTS**     JNB        MOVSW      SHR
  1480.   CMC        JNBE       MUL        SLDT**
  1481.   CMP        JNE        NEG        SMSW**
  1482.   CMPSB      JNLE       NOP        STC
  1483.   CMPSW      JNO        NOT        STD
  1484.   CWD        JNP        OR         STI
  1485.   DAA        JO         OUT        STOSB
  1486.   DAS        JP         OUTSB      STOSW
  1487.   DEC        JS         OUTSW      STR**
  1488.   DIV        LAHF       POP        SUB
  1489.   ENTER*     LAR**      POPA*      TEST
  1490.   ESC        LDS        POPF       WAIT
  1491.   HLT        LEA        PUSH       VERR**
  1492.   IDIV       LEAVE      PUSHA*     VERW**
  1493.   IMUL       LES        PUSHF      XCHG
  1494.   IN         LGDT**     RCL        XLAT
  1495.                                    XOR
  1496.   ___________________________________________
  1497.  
  1498. * Available only when running on the 186 and 286 processor
  1499. ** Available only when running on the 286 processor
  1500.  
  1501.  
  1502. TDW supports all 80386 and 80387 instruction mnemonics and registers:
  1503.  
  1504.  
  1505. 80386 instruction mnemonics
  1506. _________________________________________
  1507.  
  1508.   BSF        LSS         SETG        SETS
  1509.   BSR        MOVSX       SETL        SHLD
  1510.   BT         MOVZX       SETLE       SHRD
  1511.   BTC        POPAD       SETNB       CMPSD
  1512.   BTR        POPFD       SETNE       STOSD
  1513.   BTS        PUSHAD      SETNL       LODSD
  1514.   CDQ        PUSHFD      SETNO       MOVSD
  1515.   CWDE       SETA        SETNP       SCASD
  1516.   IRETD      SETB        SETNS       INSD
  1517.   LFS        SETBE       SETO        OUTSD
  1518.   LGS        SETE        SETP        JECXZ
  1519. __________________________________________
  1520.  
  1521. 80486 instruction mnemonics
  1522. _________________________________________
  1523.  
  1524.        BSWAP               INVLPG
  1525.        CMPXCHG             WBINVD
  1526.        INVD                XADD
  1527. _________________________________________
  1528.  
  1529.  80386 registers
  1530. _________________________________________
  1531.  
  1532.        EAX                 EDI
  1533.        EBX                 EBP
  1534.        ECX                 ESP
  1535.        EDX                 FS
  1536.        ESI                 GS
  1537. _________________________________________
  1538.  
  1539. CPU registers
  1540. __________________________________________________________________
  1541.  
  1542. Byte registers            AH, AL, BH, BL, CH, CL, DH, DL
  1543.  
  1544. Word registers            AX, BX, CX, DX, SI, DI, SP, BP, FLAGS
  1545.  
  1546. Segment registers         CS, DS, ES, SS
  1547.  
  1548. Floating registers        ST, ST(0), ST(1), ST(2), ST(3), ST(4),
  1549.                           ST(5), ST(6), ST(7)
  1550. ___________________________________________________________________
  1551.  
  1552. Special keywords
  1553. _________________________________________
  1554.  
  1555.        WORD PTR            TBYTE PTR
  1556.        BYTE PTR            NEAR
  1557.        DWORD PTR           FAR
  1558.        QWORD PTR           SHORT
  1559. _________________________________________
  1560.  
  1561. 8087/80287 numeric coprocessor instruction mnemonics
  1562. ____________________________________________________
  1563.   FABS       FIADD      FLDL2E     FST
  1564.   FADD       FIACOM     FLDL2T     FSTCW
  1565.   FADDP      FIACOMP    FLDPI      FSTENV
  1566.   FBLD       FIDIV      FLDZ       FSTP
  1567.   FBSTP      FIDIVR     FLD1       FSTSW**
  1568.   FCHS       FILD       FMUL       FSUB
  1569.   FCLEX      FIMUL      FMULP      FSUBP
  1570.   FCOM       FINCSTP    FNOP       FSUBR
  1571.   FCOMP      FINIT      FNSTS**    FSUBRP
  1572.   FCOMPP     FIST       FPATAN     FTST
  1573.   FDECSTP    FISTP      FPREM      FWAIT
  1574.   FDISI      FISUB      FPTAN      FXAM
  1575.   FDIV       FISUBR     FRNDINT    FXCH
  1576.   FDIVP      FLD        FRSTOR     FXTRACT
  1577.   FDIVR      FLDCWR     FSAVENT    FYL2X
  1578.   FDIVRP     FLDENV     FSCALE     FYL2XPI
  1579.   FENI       FLDLG2     FSETPM*    F2XM1
  1580.   FFREE      FLDLN2     FSQRT
  1581. _____________________________________________________
  1582.  
  1583. * Available only when running on the 287 numeric coprocessor.
  1584. ** On the 80287, the fstsw instruction can use the AX register as an operand,
  1585.    as well as the normal memory operand.
  1586.  
  1587.  
  1588. 80387 instruction mnemonics
  1589. _________________________________________
  1590.  
  1591.        FCOS                FUCOM
  1592.        FSIN                FUCOMP
  1593.        FPREM1              FUCOMPP
  1594.        FSINCOS
  1595. _________________________________________
  1596.  
  1597. The 80x87 coprocessor chip and emulator
  1598. =======================================
  1599.  
  1600. This section is for programmers who are familiar with the operation
  1601. if the 80x87 math coprocessor.  If your program uses floating-point
  1602. numbers, TDW lets you examine and change the state of the numeric
  1603. coprocessor or, if the coprocessor is emulated, examine the state of the
  1604. software emulator. (Windows permits you only to examine the state of the
  1605. emulator, not to change it.)  You don't need to use the capabilities
  1606. described in this chapter to debug programs that use floating-point numbers,
  1607. although some very subtle bugs may be easier to find.
  1608.  
  1609. In this section, we discuss the differences between the 80x87 chip and
  1610. the software emulator. We also describe the Numeric Processor window and
  1611. show you how to examine and modify the floating-point registers, the status
  1612. bits, and the control bits.
  1613.  
  1614.  
  1615. The 80x87 chip vs. the emulator
  1616. ===============================
  1617.  
  1618. TDW automatically detects whether your program is using the math chip or the
  1619. emulator and adjusts its behavior accordingly.
  1620.  
  1621. Note that most programs use either the emulator or the math chip, not both
  1622. within the same program. If you have written special assembler code that
  1623. uses both, TDW won't be able to show you the status of the math chip; it
  1624. reports on the emulator only.
  1625.  
  1626.  
  1627. The Numeric Processor window
  1628. ============================
  1629.  
  1630. You create a Numeric Processor window by choosing the View|Numeric Processor
  1631. command from the menu bar. The line at the top of the window shows the
  1632. current instruction pointer, opcode, and data pointer. The instruction
  1633. pointer is both shown as a 20-bit physical address. The data pointer is
  1634. either a 16-bit or a 20-bit address, depending on the memory model. You
  1635. can convert 20-bit addresses to segment and offset form by using the first
  1636. four digits as the segment value and the last digit as the offset value.
  1637.  
  1638. For example, if the top line shows IPTR=5A669, you can treat this as the
  1639. address 5a66:9 if you want to examine the current data and instruction in
  1640. a CPU window. This window has three panes: The left pane (Register pane)
  1641. shows the contents of the floating-point registers, the middle pane
  1642. (Control pane) shows the control flags, and the right pane (Status pane)
  1643. shows the status flags.
  1644.  
  1645.  
  1646. The top line shows you the following information about the last floating-
  1647. point operation that was executed:
  1648.  
  1649. o Emulator indicates that the numeric processor is being emulated. If there
  1650.   were a numeric processor, 8087, 80287, 80387, or 80486 would appear instead.
  1651.  
  1652. o The IPTR shows the 20-bit physical address from which the last floating-
  1653.   point instruction was fetched.
  1654.  
  1655. o The OPCODE shows the instruction type that was fetched.
  1656.  
  1657. o The OPTR shows the 16-bit or 20-bit physical address of the memory address
  1658.   that the instruction referenced, if any.
  1659.  
  1660.  
  1661. The Register pane
  1662. -----------------
  1663.  
  1664.     The 80-bit floating-point registers
  1665.     -----------------------------------
  1666.  
  1667.     The Register pane shows each of the floating-point registers, ST(0) to
  1668.     ST(7), along with its status (valid/zero/special/empty). The contents
  1669.     are shown as an 80-bit floating-point number.
  1670.  
  1671.     If you've zoomed the Numeric Processor window (by pressing F5) or made
  1672.     it wider by using Window|Size/Move, you'll also see the floating-point
  1673.     registers displayed as raw hex bytes.
  1674.  
  1675.  
  1676.     The Register pane local menu
  1677.     ----------------------------
  1678.     ___________
  1679.    | Zero      |
  1680.    | Empty     |
  1681.    | Change...   |
  1682.    |___________|
  1683.  
  1684.     To bring up the Register pane local menu, press Alt-F10, or use the Ctrl
  1685.     key with the first letter of the desired command to directly access the
  1686.     command.
  1687.  
  1688.     Zero
  1689.     ----
  1690.  
  1691.     Sets the value of the currently highlighted register to zero.
  1692.  
  1693.     Empty
  1694.     -----
  1695.  
  1696.     Sets the value of the currently highlighted register to empty. This is a
  1697.     special status that indicates that the register no longer contains valid
  1698.     data.
  1699.  
  1700.     Change
  1701.     ------
  1702.  
  1703.     Loads a new value into the currently highlighted register. You are
  1704.     prompted for the value to load. You can enter an integer or floating-
  1705.     point value, using the current language's expression parser.  The value
  1706.     you enter is automatically converted to the 80-bit temporary real format
  1707.     used by the numeric coprocessor.
  1708.  
  1709.     You can also invoke this command by simply starting to type the new value
  1710.     for the floating-point register. A dialog box appears, exactly as if you
  1711.     had specified the Change command.
  1712.  
  1713.  
  1714. The Control pane
  1715. ----------------
  1716.  
  1717.     The control bits
  1718.     ----------------
  1719.  
  1720.     The following table lists the different control flags and how they appear
  1721.     in the Control pane:
  1722. _________________________________________
  1723.  
  1724.    Name in pane         Flag description__
  1725.  
  1726.       im                Invalid operation mask
  1727.       dm                Denormalized operand mask
  1728.       zm                Zero divide mask
  1729.       om                Overflow mask
  1730.       um                Underflow mask
  1731.       pm                Precision mask
  1732.       iem               Interrupt enable mask (8087 only)
  1733.       pc                Precision control
  1734.       rc                Rounding control
  1735.       ic                Infinity control__
  1736.  
  1737.  
  1738.     The Control pane local menu
  1739.     ---------------------------
  1740.        ________
  1741.       | Toggle |
  1742.       |________|
  1743.  
  1744.     Press Tab to go to the Control pane, then press Alt-F10 to pop up the
  1745.     local menu. (Alternatively, you can use the Ctrl key with the first letter
  1746.     of the desired command to access it.)
  1747.  
  1748.     Toggle
  1749.     ------
  1750.  
  1751.     Cycles through the values that the currently highlighted control flag
  1752.     can be set to. Most flags can only be set or cleared (0 or 1), so this
  1753.     command just toggles the flag to the other value. Some other flags have
  1754.     more than two values; for those flags, this command increments the flag
  1755.     value until the maximum value is reached, and then sets it back to zero.
  1756.  
  1757.     You can also toggle the control flag values by highlighting them and
  1758.     pressing Enter.
  1759.  
  1760.  
  1761. The Status pane
  1762. ---------------
  1763.  
  1764.  
  1765.     The status bits
  1766.     ---------------
  1767.  
  1768.     The following table lists the different status flags and how they appear
  1769.     in the Status pane:
  1770. ____________________________________
  1771.  
  1772.    Name in pane         Flag description__
  1773.  
  1774.       ie                Invalid operation
  1775.       de                Denormalized operand
  1776.       ze                Zero divide
  1777.       oe                Overflow
  1778.       ue                Underflow
  1779.       pe                Precision
  1780.       ir                Interrupt request
  1781.       cc                Condition code
  1782.       st                Stack top pointer_
  1783.  
  1784.  
  1785.     The Status pane local menu
  1786.     --------------------------
  1787.        ________
  1788.       | Toggle |
  1789.       |________|
  1790.  
  1791.     Press Tab to move to the Statuspane, then press Alt-F10 to pop up the
  1792.     local menu. (You can also use the Ctrl key with the first letter of the
  1793.     desired command to access the command directly.)
  1794.  
  1795.  
  1796.     Toggle
  1797.     ------
  1798.  
  1799.     Cycles through the values that the currently highlighted status flag
  1800.     can be set to. Most flags can only be set or cleared (0 or 1), so this
  1801.     command just toggles the flag to the other value. Some other flags have
  1802.     more than two values; for those flags, this command increments the
  1803.     flag value until the maximum value is reached, and then sets it back to
  1804.     zero.
  1805.  
  1806.     You can also toggle the status flag values by highlighting them and
  1807.     pressing Enter.
  1808.  
  1809.